/*
 * Copyright (c) 2011 Imre Fazekas.
 * All rights reserved.
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 * Neither the name of the Brillien nor the names of its
 * terms and concepts may be used to endorse or promote products derived from this
 * software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.vii.streamline.services;

import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Service class to handle regular expressioon-based operations
 */
public class RegularServices {

    private static Hashtable<String, Pattern> patterns;

    /**
     * Built-in regular expression to handle URL cutting from the beginning of a string
     */
    public static String            URL_PROTOCOL_CUTTER_PATTERN = "(?<=http://).*";

    public static String            IP_ADDRESS = "(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)";

    public static String            EMAIL_ADDRESS = "^[A-Za-z0-9](([_\\.\\-]?[a-zA-Z0-9]+)*)@([A-Za-z0-9]+)(([\\.\\-]?[a-zA-Z0-9]+)*)\\.([A-Za-z]{2,})$";

    static{
        patterns = new Hashtable<String, Pattern>();
    }

    /**
     * Register a new regular pattern
     */
    public static Pattern registerPattern( String regularExpression ){  Pattern p;
        if( (p = patterns.get(regularExpression)) == null )
            patterns.put( regularExpression, p = Pattern.compile( regularExpression ) );
        return p;
    }

    /**
     * Decides weather the original string matches the pattern
     * @param original Original String
     * @param pattern Regular Expression Pattern object
     * @return decision about matching with the given pattern
     */
    public static boolean matches(String original, Pattern pattern) {
        Matcher matcher = pattern.matcher(original);
        return matcher.matches();
    }

    /**
     * Decides weather the original string matches the pattern
     * @param original Original String
     * @param regularExpression Regular Expression String
     * @return decision about matching with the given pattern
     */
    public static boolean matches(String original, String regularExpression) {
        return matches( original, registerPattern(regularExpression) );
    }


    /**
     * Searches a regulare pattern in a String.
     * @param original Original String
     * @param pattern Regular Expression Pattern object
     * @return The first match of the resulted query
     */
    public static List<String> getMathes(String original, Pattern pattern) {
        ArrayList<String> l = new ArrayList<String>();

        Matcher matcher = pattern.matcher(original);
        
        while (matcher.find())
            l.add( matcher.group() );
        
        return l;
    }

    /**
     * Searches a regulare pattern in a String.
     * @param original Original String
     * @param regularExpression Regular Expression String
     * @return The first match of the resulted query
     */
    public static List<String> getMathes(String original, String regularExpression) {
        return getMathes( original, registerPattern(regularExpression) );
    }

    public static Pattern getPatternFromWildChar( String pattern ){
        StringBuilder builder = new StringBuilder();
        for( int i=0; i<pattern.length(); ++i ){
            if( pattern.charAt(i) == '*' )
                builder.append( ".*" );
            else if( pattern.charAt(i) == '?' )
                builder.append( ".??" );
            else if( Character.isJavaIdentifierPart( pattern.charAt(i) ) )
                builder.append( pattern.charAt(i) );
            else
                builder.append( "\\" + pattern.charAt(i) );
        }
        Pattern p = Pattern.compile( builder.toString() );
        return p;
    }

    public static String cut( String original, String... patterns ){
        String res = original;
        for( String pattern : patterns ){
            for( String s : getMathes( res, pattern ) ){
                res = s; break;
            }
        }
        return res;
    }

}
